package base

// 用于从方法的code属性中读取操作指令或者操作数
// 一个方法的code属性是一个byte数组。这个类底层每次调用readUint8读取一个byte，并且将计数器+1
// 当需要一个int16时，将进行两次readUint8方法的调用，这意味着计数器的值将会+2
type BytecodeReader struct {
	// 一个byte Slice，可以理解成一个byte数组
	code []byte
	pc   int
}

// 替换掉这个阅读器内部的code和pc指针。目的是为了能在各个方法跳转时共享阅读器，不用创建多个
// pc指针在每个方法的栈帧中都有备份，每次方法跳转后都从栈帧中重新拿pc值
func (self *BytecodeReader) Reset(code []byte, pc int) {
	self.pc = pc
	self.code = code
}

func (self *BytecodeReader) ReadUint8() uint8 {
	i := self.code[self.pc]
	self.pc++
	return i
}

func (self *BytecodeReader) ReadInt8() int8 {
	return int8(self.ReadUint8())
}

func (self *BytecodeReader) ReadUint16() uint16 {
	byte1 := uint16(self.ReadUint8())
	byte2 := uint16(self.ReadUint8())
	return byte1<<8 | byte2
}

func (self *BytecodeReader) ReadInt16() int16 {
	return int16(self.ReadUint16())
}

func (self *BytecodeReader) ReadUint32() uint32 {
	byte1 := uint32(self.ReadUint8())
	byte2 := uint32(self.ReadUint8())
	byte3 := uint32(self.ReadUint8())
	byte4 := uint32(self.ReadUint8())
	return byte1<<24 | byte2<<16 | byte3<<8 | byte4
}

func (self *BytecodeReader) ReadInt32() int32 {
	return int32(self.ReadUint32())
}

// 读取对其填充的字节，读到之后直接丢弃
func (self *BytecodeReader) SkipPadding() {
	// class文件中某些内容要求以四字节对齐
	for self.pc %4 !=0 {
		self.ReadUint8()
	}
}

// 从byte数组中读取n个int32，并且存入切片中
func (self *BytecodeReader) ReadInt32s(n int32) []int32 {
	ints := make([]int32,n)
	for i := range ints {
		ints[i] = self.ReadInt32()
	}
	return ints
}
func (self *BytecodeReader) PC() int {
	return self.pc
}
